﻿using FxFlowWindowBase.Win.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows;

namespace FormView.UI.PromptView
{
	public class PromptFormWindow : FormWindowBase
	{
		/// <summary>
		/// 默认锁
		/// </summary>
		private static readonly object mLocker = new object();

		/// <summary>
		/// 注册的所有prompt组件
		/// </summary>
		private static readonly Dictionary<string, IPromptViewControl> PromptViewControls =
			new Dictionary<string, IPromptViewControl>();

		/// <summary>
		/// 已经初始化的prompt组件
		/// </summary>
		private LinkedList<FrameworkElement> mPromptViews = new LinkedList<FrameworkElement>();

		public PromptFormWindow(string @namespace) : base(@namespace)
		{
			EnableFooterBar();	
		}

		static PromptFormWindow()
		{
			RegisterPromptView(PromptNumberView.TagName, new PromptNumberView());
			RegisterPromptView(PromptTextView.TagName, new PromptTextView());
			RegisterPromptView(PromptPathView.TagName, new PromptPathView());
			RegisterPromptView(PromptFileView.TagName, new PromptFileView());
			RegisterPromptView("new_file", new PromptFileView());
			RegisterPromptView(PromptSpeedView.TagName, new PromptSpeedView());
			RegisterPromptView("setting", new PromptSpeedView());
			RegisterPromptView(PromptCheckBoxView.TagName, new PromptCheckBoxView());
			RegisterPromptView(PromptComboBoxView.TagName, new PromptComboBoxView());
			RegisterPromptView(PromptSwitchView.TagName, new PromptSwitchView());
		}

		/// <summary>
		/// 注册PromptView
		/// </summary>
		/// <param name="tagName">标签名</param>
		/// <param name="promptViewControl">组件控制器</param>
		public static void RegisterPromptView(string tagName, IPromptViewControl promptViewControl)
		{
			Monitor.Enter(mLocker);
			if (PromptViewControls.ContainsKey(tagName))
			{
				Monitor.Exit(mLocker);
				throw new ArgumentException($"已经存在同名标签:{tagName}, PromptViewControl注册失败");
			}
			PromptViewControls.Add(tagName, promptViewControl);
			Monitor.Exit(mLocker);
		}

		public void LoadView(LinkedList<PromptDataView> dataViews)
		{
			ShowLoading("加载中...");
			foreach (PromptDataView promptDataView in dataViews)
			{
				if (!PromptViewControls.ContainsKey(promptDataView.PromptTag))
				{
					CloseLoading();
					throw new Exception($"不存在的Prompt类型: {promptDataView.PromptTag}");
				}

				IPromptViewControl promptViewControl = PromptViewControls[promptDataView.PromptTag];
				FrameworkElement element = promptViewControl.GetElement(this, promptDataView.TipText, promptDataView.DefaultValue);
				if (element == null)
				{
					CloseLoading();
					throw new NullReferenceException($"Prompt类型:{promptDataView.PromptTag}, 生成的组件实例不可为NULL.");
				}

				if (element.Tag != null)
				{
					CloseLoading();
					throw new Exception("Prompt View组件的Tag值为预留，不可使用");
				}
				element.Tag = promptDataView.PromptTag;
				AddControl(element);
				mPromptViews.AddLast(element);
			}
			CloseLoading();
			this.SizeChanged += (sender, args) =>
			{
				ShowLoading("重绘组件中...");
				foreach (FrameworkElement element in mPromptViews)
				{
					string tag = element.Tag.ToString();
					if (!PromptViewControls.ContainsKey(tag))
					{
						CloseLoading();
						throw new Exception("Prompt View内部异常，请勿使用组件的Tag属性");
					}
					IPromptViewControl promptViewControl = PromptViewControls[tag];
					promptViewControl.OnRenderView(this, element);
				}
				CloseLoading();
			};
		}

		protected override FormResult GetFormResult()
		{
			FormResult result = new FormResult(mPromptViews.Select(view =>
			{
				string type = view.Tag.ToString();
				if (!PromptViewControls.ContainsKey(type))
				{
					throw new Exception("Prompt View内部异常，请勿使用组件的Tag属性");
				}

				object res = null;
				try
				{
					res = PromptViewControls[type].GetValue(view);
				}
				catch (Exception e)
				{
					Console.WriteLine($"{e.StackTrace} : {e.Message}");
				}

				return res;
			}).ToList());
			return result;
		}

		protected override FormResult OnUserCloseWinGetResult()
		{
			return new FormResult(null);
		}
	}
}
